<template>
  <div class="image-frame" :class="{ rounded: rounded, shadow: shadow }">
    <!-- 加载状态 -->
    <div v-if="isLoading" class="loading-state">
      <div class="spinner"></div>
    </div>

    <!-- 错误状态 -->
    <div v-else-if="hasError || !src" class="error-state">
      <slot name="error">
        <span class="error-icon">⚠️</span>
        <p class="error-text">{{ errorText }}</p>
      </slot>
    </div>
    
    <!-- 图片展示 -->
    <img
      v-else
      :src="src"
      :alt="alt"
      @error="handleImageError"
      :class="{ contain: fit === 'contain', cover: fit === 'cover' }"
    />

    <!-- 图片描述 -->
    <p v-if="caption" class="image-caption">{{ caption }}</p>
  </div>
</template>

<script setup>
import { ref } from "vue";

// 组件属性
const props = defineProps({
  // 图片源地址
  src: {
    type: String,
    required: true,
  },
  // 图片替代文本
  alt: {
    type: String,
    default: "图片",
  },
  // 图片适应方式 (contain/cover)
  fit: {
    type: String,
    default: "contain",
    validator: (value) => ["contain", "cover"].includes(value),
  },
  // 是否显示圆角
  rounded: {
    type: Boolean,
    default: true,
  },
  // 是否显示阴影
  shadow: {
    type: Boolean,
    default: true,
  },
  // 图片描述文字
  caption: {
    type: String,
    default: "",
  },
  // 错误提示文本
  errorText: {
    type: String,
    default: "图片加载失败|暂无图片生成",
  },
});

// 状态管理
const isLoading = ref(false);
const hasError = ref(false);

// 图片加载成功处理
const handleImageLoad = () => {
  isLoading.value = false;
  hasError.value = false;
};

// 图片加载失败处理
const handleImageError = () => {
  isLoading.value = false;
  hasError.value = true;
};
</script>

<style scoped>
.image-frame {
  position: relative;
  display: inline-block;
  box-sizing: border-box;
  overflow: hidden;
  background-color: #f5f5f5;
  /* max-width: 100%; */
  /* flex: 1; */
    background: rgba(255, 255, 255, 0.9);
  /* width: 700px; */
  width: 50%;
  border-radius: 12px;
  box-shadow: 0 8px 32px rgba(31, 38, 135, 0.37);
  overflow: hidden;
  /* width: 100%; */
}

/* 图片样式 */
.image-frame img {
  display: block;
  width: 100%;
  height: 100%;
  transition: opacity 0.3s ease;
}

/* 图片适应方式 */
.contain {
  object-fit: contain;
}

.cover {
  object-fit: cover;
}

/* 圆角样式 */
.rounded {
  border-radius: 8px;
}

/* 阴影样式 */
.shadow {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

/* 加载状态 */
.loading-state {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  min-width: 100px;
  min-height: 100px;
}

.spinner {
  width: 24px;
  height: 24px;
  border: 3px solid rgba(0, 0, 0, 0.1);
  border-radius: 50%;
  border-top-color: #333;
  animation: spin 1s ease-in-out infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* 错误状态 */
.error-state {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  min-width: 100px;
  min-height: 100px;
  color: #e53e3e;
  padding: 16px;
  text-align: center;
}

.error-icon {
  font-size: 24px;
  margin-bottom: 8px;
}

.error-text {
  margin: 0;
  font-size: 14px;
}

/* 图片描述 */
.image-caption {
  margin: 8px 0 0 0;
  padding: 0 8px 8px;
  font-size: 14px;
  color: #666;
  text-align: center;
}
</style>
